package org.raymond.iworks.study.netty.atguigu.bio;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Slf4j
public class BioServer {
    public static void main(String[] args) throws IOException {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 3,
                0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
        ServerSocket server =  new ServerSocket(6666);
        log.debug("服务器启动了");
        while(true) {
            Socket socket = server.accept();
            // mac上三次握手之后还有一次server到client的ACK,然后才建立连接,打印此日志
            log.debug("连接到一个客户端");
            // socket.setSoTimeout(1000); // Read timed out
            pool.execute(() -> {
                try {
                    handler(socket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }

    public static void handler(Socket socket) throws IOException {
        try {
            log.info("开始处理"); // 从接受到客户端到这里耗时2ms
            InputStream is = socket.getInputStream();
            byte[] bytes = new byte[1024];
            StringBuilder sb = new StringBuilder();
            while(true){
                log.info("开始读数据");
                // 数据理论上读完,实际上还要再多读一次,确认是否读完.
                // 这一次读也会消耗350ms, 读到的数据为空, read=0
                int read = is.read(bytes); // cost 350 ms
                //int read = is.read(); // cost 350 ms
                log.info("读数据完毕");
                if(read>0) {
                    String msg = new String(bytes, 0, read);
                    //String msg = new String();
                    sb.append(msg);
                    log.info("组装数据");
                }else{
                    break;
                }
            }
            log.info("receive: "+sb); // cost 1 ms
        } finally {
            log.info("尝试关闭服务端链接.");
            socket.close();
            log.info("关闭服务端链接成功."); // cost 4 ms
        }
    }
}
